#include <pthread.h>
#include <unistd.h>
#include <ctime>

#include "Task.hpp"
#include "BlockQueue.hpp"

int myAdd(int x, int y)
{
    return x + y;
}

// 生产者启动例程
void *producer(void *args)
{
    BlockQueue<Task> *bq = (BlockQueue<Task> *)args;

    while (true)
    {
        // 生产数据(自己生产/网络获取/用户输入)
        int x = rand() % 10 + 1;
        usleep(rand() % 1000); // 模拟数据生成的过程
        int y = rand() % 5 + 1;

        Task t(x, y, myAdd);

        // 发送数据
        bq->push(t);

        // for debug：输出消息
        std::cout << pthread_self() << " productor: " << t._x << "+" << t._y << "= ?" << std::endl;
        sleep(1);
    }
    return nullptr;
}

// 消费者启动例程
void *consumer(void *args)
{
    BlockQueue<Task> *bq = (BlockQueue<Task> *)args;

    while (true)
    {
        // 接收数据
        Task t;
        bq->pop(&t);

        // 处理数据
        std::cout << pthread_self() << " consumer : " << t._x << "+" << t._y << "=" << t() << std::endl;
    }

    return nullptr;
}

int main()
{
    srand((uint64_t)time(nullptr) ^ getpid() ^ 0x13254);

    BlockQueue<Task> *bq = new BlockQueue<Task>();

    pthread_t consmr[2], prodcr[2];
    pthread_create(consmr, nullptr, consumer, bq);
    pthread_create(consmr + 1, nullptr, consumer, bq);

    pthread_create(prodcr, nullptr, producer, bq);
    pthread_create(prodcr + 1, nullptr, producer, bq);

    pthread_join(consmr[0], nullptr);
    pthread_join(consmr[1], nullptr);

    pthread_join(prodcr[0], nullptr);
    pthread_join(prodcr[1], nullptr);

    delete bq;

    return 0;
}

